using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;
using Work.API.Applications.Write.Commands;
using Work.API.Dtos.DrugManagement;
using Work.ErrorCode;

namespace WinFormsApp1.DrugManagement
{
    /// <summary>
    /// 查看检药单窗体（用于查看检药单模块）
    /// 功能：
    /// 1. 左侧显示未打单列表（已支付但未创建检药单的处方明细）
    /// 2. 右侧显示已打单未发药列表（已创建检药单但未发药）
    /// 3. 支持"打单"操作（从左侧选择处方明细，创建检药单）
    /// 4. 支持"发药"操作（从右侧选择检药单，执行药品出库）
    /// </summary>
    public partial class InspectionListForm : Form
    {
        private const string ApiBaseUrl = "http://localhost:5044";
        private readonly HttpClient _httpClient;
        private readonly JsonSerializerOptions _jsonOptions;
        private List<UnbilledPrescriptionDto> _unbilledPrescriptions;
        private List<InspectionListDto> _inspectionList;
        private UnbilledPrescriptionDto? _selectedUnbilledPrescription;
        private InspectionListDto? _selectedInspection;

        public InspectionListForm()
        {
            InitializeComponent();
            _httpClient = new HttpClient { BaseAddress = new Uri(ApiBaseUrl) };
            _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
            _unbilledPrescriptions = new List<UnbilledPrescriptionDto>();
            _inspectionList = new List<InspectionListDto>();

            // 初始化时间筛选选项
            InitializeTimeFilter();
            // 加载数据
            LoadUnbilledPrescriptions("全部");
            LoadInspectionList("全部");
        }

        /// <summary>
        /// 初始化时间筛选选项
        /// </summary>
        private void InitializeTimeFilter()
        {
            // 默认选择"全部"
            if (rbAll != null)
            {
                rbAll.Checked = true;
            }
        }

        /// <summary>
        /// 加载未打单处方明细列表（左侧）
        /// </summary>
        private async void LoadUnbilledPrescriptions(string timeFilterType)
        {
            try
            {
                var registrationNum = txtRegistrationNum.Text?.Trim();
                var patientName = txtPatientName.Text?.Trim();

                var url = $"api/Drug/GetUnbilledPrescriptions?timeFilterType={Uri.EscapeDataString(timeFilterType)}";

                if (!string.IsNullOrWhiteSpace(registrationNum))
                    url += $"&registrationNum={Uri.EscapeDataString(registrationNum)}";
                if (!string.IsNullOrWhiteSpace(patientName))
                    url += $"&patientName={Uri.EscapeDataString(patientName)}";

                var response = await _httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                var json = await response.Content.ReadAsStringAsync();
                var apiResult = JsonSerializer.Deserialize<ApiResult<List<UnbilledPrescriptionDto>>>(json, _jsonOptions);

                if (apiResult != null && apiResult.Code == ApiEnum.成功 && apiResult.Data != null)
                {
                    _unbilledPrescriptions = apiResult.Data;
                    RefreshUnbilledDataGridView();
                }
                else
                {
                    _unbilledPrescriptions = new List<UnbilledPrescriptionDto>();
                    RefreshUnbilledDataGridView();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载未打单列表失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 加载检药单列表（右侧，已打单未发药）
        /// </summary>
        private async void LoadInspectionList(string timeFilterType)
        {
            try
            {
                var registrationNum = txtRegistrationNum.Text?.Trim();
                var patientName = txtPatientName.Text?.Trim();

                var url = $"api/Drug/GetInspectionList?timeFilterType={Uri.EscapeDataString(timeFilterType)}";

                if (!string.IsNullOrWhiteSpace(registrationNum))
                    url += $"&registrationNum={Uri.EscapeDataString(registrationNum)}";
                if (!string.IsNullOrWhiteSpace(patientName))
                    url += $"&patientName={Uri.EscapeDataString(patientName)}";

                var response = await _httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                var json = await response.Content.ReadAsStringAsync();
                var apiResult = JsonSerializer.Deserialize<ApiResult<List<InspectionListDto>>>(json, _jsonOptions);

                if (apiResult != null && apiResult.Code == ApiEnum.成功 && apiResult.Data != null)
                {
                    _inspectionList = apiResult.Data;
                    RefreshInspectionDataGridView();
                }
                else
                {
                    _inspectionList = new List<InspectionListDto>();
                    RefreshInspectionDataGridView();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载已打单未发药列表失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 刷新未打单数据表格（左侧）
        /// </summary>
        private void RefreshUnbilledDataGridView()
        {
            if (dgvUndispensed != null)
            {
                dgvUndispensed.DataSource = null;
                dgvUndispensed.DataSource = _unbilledPrescriptions;
                SetUnbilledColumnHeaders(dgvUndispensed);
            }
            }

        /// <summary>
        /// 刷新已打单未发药数据表格（右侧）
        /// </summary>
        private void RefreshInspectionDataGridView()
        {
            if (dgvDispensed != null)
            {
                dgvDispensed.DataSource = null;
                dgvDispensed.DataSource = _inspectionList;
                SetInspectionColumnHeaders(dgvDispensed);
            }
        }

        /// <summary>
        /// 设置未打单表格的中文列标题
        /// </summary>
        private void SetUnbilledColumnHeaders(DataGridView dgv)
        {
            if (dgv.Columns.Count > 0)
            {
                var columnHeaders = new Dictionary<string, string>
                {
                    { "PrescriptionItemId", "处方明细ID" },
                    { "AppointmentId", "预约编号" },
                    { "PatientId", "患者ID" },
                    { "RegistrationNum", "挂号编号" },
                    { "PatientName", "患者姓名" },
                    { "GenderText", "性别" },
                    { "Age", "年龄" },
                    { "IdCard", "身份证号" },
                    { "CardNumber", "卡号" },
                    { "DrugName", "药品名称" },
                    { "MedicineName", "药品名称" },
                    { "DrugId", "药品ID" },
                    { "UnitPrice", "单价" },
                    { "Quantity", "数量" },
                    { "TotalAmount", "总金额" },
                    { "CreateTime", "开药时间" },
                    { "CreateBy", "开药医生" }
                };

                foreach (DataGridViewColumn column in dgv.Columns)
                {
                    // 隐藏英文列名Gender（只显示中文的GenderText）
                    if (column.Name == "Gender")
                    {
                        column.Visible = false;
                        continue;
                    }
                    
                    if (columnHeaders.ContainsKey(column.Name))
                    {
                        column.HeaderText = columnHeaders[column.Name];
                    }
                    
                    // 格式化单价和总金额为两位小数
                    if (column.Name == "UnitPrice" || column.Name == "TotalAmount")
                    {
                        column.DefaultCellStyle.Format = "F2";
                        column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                    }
                }
            }
        }

        /// <summary>
        /// 设置检药单表格的中文列标题
        /// </summary>
        private void SetInspectionColumnHeaders(DataGridView dgv)
        {
            if (dgv.Columns.Count > 0)
            {
                var columnHeaders = new Dictionary<string, string>
                {
                    { "InspectionId", "检药单ID" },
                    { "PrescriptionItemId", "处方明细ID" },
                    { "AppointmentId", "预约编号" },
                    { "PatientId", "患者ID" },
                    { "RegistrationNum", "挂号编号" },
                    { "PatientName", "患者姓名" },
                    { "GenderText", "性别" },
                    { "Age", "年龄" },
                    { "IdCard", "身份证号" },
                    { "CardNumber", "卡号" },
                    { "DrugId", "药品ID" },
                    { "DrugName", "药品名称" },
                    { "InspectionStatus", "检查状态" },
                    { "InspectionDate", "检查日期" },
                    { "Inspector", "检查人" },
                    { "InspectionResult", "检查结果" },
                    { "HandlingMethod", "处理方式" },
                    { "IsDispensed", "是否已发药" },
                    { "DispensedDate", "发药日期" },
                    { "CreateTime", "创建时间" },
                    { "Remarks", "备注" }
                };

                foreach (DataGridViewColumn column in dgv.Columns)
                {
                    // 隐藏英文列名Gender（只显示中文的GenderText）
                    if (column.Name == "Gender")
                    {
                        column.Visible = false;
                        continue;
                    }
                    
                    if (columnHeaders.ContainsKey(column.Name))
                    {
                        column.HeaderText = columnHeaders[column.Name];
                    }
                    
                    // 将IsDispensed的true/false转换为中文
                    if (column.Name == "IsDispensed")
                    {
                        column.DefaultCellStyle.Format = "";
                        // 移除已有的事件处理器，避免重复绑定
                        dgv.CellFormatting -= DgvDispensed_IsDispensedFormatting;
                        dgv.CellFormatting += DgvDispensed_IsDispensedFormatting;
                }
            }
            }
        }

        /// <summary>
        /// 已打单列表IsDispensed列的格式化事件
        /// </summary>
        private void DgvDispensed_IsDispensedFormatting(object? sender, DataGridViewCellFormattingEventArgs e)
        {
            try
            {
                if (sender is DataGridView dgv && e.ColumnIndex >= 0 && e.ColumnIndex < dgv.Columns.Count && 
                    dgv.Columns[e.ColumnIndex].Name == "IsDispensed")
                {
                    // 处理bool类型
                    if (e.Value is bool boolValue)
                    {
                        e.Value = boolValue ? "是" : "否";
                        e.FormattingApplied = true;
                        return;
                    }
                    
                    // 处理可空bool类型
                    if (e.Value != null && e.Value is bool?)
                    {
                        bool? nullableBool = e.Value as bool?;
                        if (nullableBool.HasValue)
                        {
                            e.Value = nullableBool.Value ? "是" : "否";
                            e.FormattingApplied = true;
                            return;
                        }
                    }
                    
                    // 处理字符串类型（可能已经是格式化后的值）
                    if (e.Value is string)
                    {
                        // 已经是字符串，不需要格式化
                        e.FormattingApplied = false;
                        return;
                    }
                }
            }
            catch
            {
                // 忽略格式化错误，使用默认显示
                e.FormattingApplied = false;
            }
        }

        /// <summary>
        /// 未打单列表数据错误事件处理
        /// </summary>
        private void DgvUndispensed_DataError(object? sender, DataGridViewDataErrorEventArgs e)
        {
            // 忽略数据错误，避免显示默认错误对话框
            e.ThrowException = false;
        }

        /// <summary>
        /// 已打单列表数据错误事件处理
        /// </summary>
        private void DgvDispensed_DataError(object? sender, DataGridViewDataErrorEventArgs e)
        {
            // 忽略数据错误，避免显示默认错误对话框
            e.ThrowException = false;
        }

        /// <summary>
        /// 时间筛选选项改变
        /// </summary>
        private void TimeFilter_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton? rb = sender as RadioButton;
            if (rb != null && rb.Checked)
            {
                string timeFilterType = rb.Text;
                LoadUnbilledPrescriptions(timeFilterType);
                LoadInspectionList(timeFilterType);
            }
        }

        /// <summary>
        /// 搜索
        /// </summary>
        private void btnSearch_Click(object sender, EventArgs e)
        {
            string timeFilterType = "全部";
            if (rbToday?.Checked == true) timeFilterType = "今天";
            else if (rbThisWeek?.Checked == true) timeFilterType = "本周";
            else if (rbThisMonth?.Checked == true) timeFilterType = "本月";
            else if (rbThisYear?.Checked == true) timeFilterType = "今年";

            LoadUnbilledPrescriptions(timeFilterType);
            LoadInspectionList(timeFilterType);
        }

        /// <summary>
        /// 打单操作（从左侧选择未打单处方明细，创建检药单）
        /// </summary>
        private async void btnCreateInspection_Click(object sender, EventArgs e)
        {
            if (_selectedUnbilledPrescription == null)
            {
                MessageBox.Show("请先在左侧未打单列表中选择要打单的处方明细", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                // 创建检药单
                var command = new CreateInspectionCommand
                {
                    PrescriptionItemId = _selectedUnbilledPrescription.PrescriptionItemId,
                    AppointmentId = _selectedUnbilledPrescription.AppointmentId,
                    PatientId = _selectedUnbilledPrescription.PatientId,
                    RegistrationNum = _selectedUnbilledPrescription.RegistrationNum,
                    PatientName = _selectedUnbilledPrescription.PatientName,
                    CardNumber = _selectedUnbilledPrescription.CardNumber,
                    DrugId = _selectedUnbilledPrescription.DrugId,
                    DrugName = _selectedUnbilledPrescription.MedicineName,
                    Remarks = "从检药单列表创建"
                };

                var json = System.Text.Json.JsonSerializer.Serialize(command);
                var content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json");

                var response = await _httpClient.PostAsync("api/Drug/CreateInspection", content);
                response.EnsureSuccessStatusCode();
                var responseJson = await response.Content.ReadAsStringAsync();
                var apiResult = System.Text.Json.JsonSerializer.Deserialize<ApiResult<int>>(responseJson, _jsonOptions);

                if (apiResult != null && apiResult.Code == ApiEnum.成功)
                {
                    MessageBox.Show("检药单创建成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    // 重新加载两个列表
                    string timeFilterType = "全部";
                    if (rbToday?.Checked == true) timeFilterType = "今天";
                    else if (rbThisWeek?.Checked == true) timeFilterType = "本周";
                    else if (rbThisMonth?.Checked == true) timeFilterType = "本月";
                    else if (rbThisYear?.Checked == true) timeFilterType = "今年";
                    LoadUnbilledPrescriptions(timeFilterType);
                    LoadInspectionList(timeFilterType);
                }
                else
                {
                    MessageBox.Show(apiResult?.Message ?? "创建失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打单失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 发药操作（从右侧选择检药单，执行药品出库）
        /// </summary>
        private async void btnDispenseDrug_Click(object sender, EventArgs e)
        {
            if (_selectedInspection == null)
            {
                MessageBox.Show("请先在右侧已打单未发药列表中选择要发药的检药单", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (_selectedInspection.IsDispensed)
            {
                MessageBox.Show("该检药单已发药", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 检查药品库存（支持根据药品ID或药品名称查找）
            var inventoryCheckResult = await CheckDrugInventory(_selectedInspection);
            if (!inventoryCheckResult.Success)
            {
                MessageBox.Show(inventoryCheckResult.Message, "库存检查", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 如果通过药品名称找到了药品，更新检药单的DrugId（用于后续出库）
            if (inventoryCheckResult.DrugId.HasValue && (!_selectedInspection.DrugId.HasValue || _selectedInspection.DrugId.Value != inventoryCheckResult.DrugId.Value))
            {
                _selectedInspection.DrugId = inventoryCheckResult.DrugId.Value;
            }

            // 打开药品出库窗体，传入检药单信息
            var outboundForm = new DrugOutboundForm(_selectedInspection);
            outboundForm.ShowDialog();

            // 发药后刷新列表
            string timeFilterType = "全部";
            if (rbToday?.Checked == true) timeFilterType = "今天";
            else if (rbThisWeek?.Checked == true) timeFilterType = "本周";
            else if (rbThisMonth?.Checked == true) timeFilterType = "本月";
            else if (rbThisYear?.Checked == true) timeFilterType = "今年";
            LoadInspectionList(timeFilterType);
        }

        /// <summary>
        /// 检查药品库存（支持根据药品ID或药品名称查找）
        /// </summary>
        private async Task<(bool Success, string Message, int? DrugId)> CheckDrugInventory(InspectionListDto inspection)
        {
            try
            {
                DrugDto? drug = null;

                // 优先使用药品ID查找
                if (inspection.DrugId.HasValue && inspection.DrugId.Value > 0)
                {
                    var response = await _httpClient.GetAsync($"api/Drug/GetDrugs?onlyEnabled=true");
                    response.EnsureSuccessStatusCode();
                    var json = await response.Content.ReadAsStringAsync();
                    var apiResult = JsonSerializer.Deserialize<ApiResult<List<DrugDto>>>(json, _jsonOptions);

                    if (apiResult != null && apiResult.Code == ApiEnum.成功 && apiResult.Data != null)
                    {
                        drug = apiResult.Data.FirstOrDefault(d => d.DrugId == inspection.DrugId.Value);
                    }
                }

                // 如果通过ID没找到，且检药单中有药品名称，则根据药品名称查找
                string? drugNameToSearch = inspection.DrugName;
                
                // 如果检药单中没有药品名称，尝试从处方明细获取
                if (string.IsNullOrWhiteSpace(drugNameToSearch))
                {
                    try
                    {
                        var prescriptionResponse = await _httpClient.GetAsync($"api/Prescription/GetByAppointment?appointmentId={inspection.AppointmentId}");
                        if (prescriptionResponse.IsSuccessStatusCode)
                        {
                            var prescriptionJson = await prescriptionResponse.Content.ReadAsStringAsync();
                            var prescriptionResult = JsonSerializer.Deserialize<ApiResult<List<Work.API.Dtos.PrescriptionItemDto>>>(prescriptionJson, _jsonOptions);
                            if (prescriptionResult != null && prescriptionResult.Code == ApiEnum.成功 && prescriptionResult.Data != null)
                            {
                                var prescriptionItem = prescriptionResult.Data.FirstOrDefault(pi => pi.PrescriptionItemId == inspection.PrescriptionItemId);
                                if (prescriptionItem != null && !string.IsNullOrWhiteSpace(prescriptionItem.MedicineName))
                                {
                                    drugNameToSearch = prescriptionItem.MedicineName;
                                }
                            }
                        }
                    }
                    catch
                    {
                        // 如果获取处方明细失败，继续使用检药单中的药品名称
                    }
                }

                if (drug == null && !string.IsNullOrWhiteSpace(drugNameToSearch))
                {
                    var response = await _httpClient.GetAsync($"api/Drug/GetDrugs?drugName={Uri.EscapeDataString(drugNameToSearch)}&onlyEnabled=true");
                    response.EnsureSuccessStatusCode();
                    var json = await response.Content.ReadAsStringAsync();
                    var apiResult = JsonSerializer.Deserialize<ApiResult<List<DrugDto>>>(json, _jsonOptions);

                    if (apiResult != null && apiResult.Code == ApiEnum.成功 && apiResult.Data != null)
                    {
                        // 精确匹配药品名称
                        drug = apiResult.Data.FirstOrDefault(d => d.DrugName == drugNameToSearch);
                        
                        // 如果精确匹配没找到，使用模糊匹配（包含）
                        if (drug == null)
                        {
                            drug = apiResult.Data.FirstOrDefault(d => d.DrugName.Contains(drugNameToSearch) || drugNameToSearch.Contains(d.DrugName));
                        }
                    }
                }

                // 如果仍然没找到药品
                if (drug == null)
                {
                    string drugInfo = "";
                    if (inspection.DrugId.HasValue && inspection.DrugId.Value > 0)
                    {
                        drugInfo = $"ID: {inspection.DrugId.Value}";
                    }
                    else if (!string.IsNullOrWhiteSpace(drugNameToSearch))
                    {
                        drugInfo = drugNameToSearch;
                    }
                    else if (!string.IsNullOrWhiteSpace(inspection.DrugName))
                    {
                        drugInfo = inspection.DrugName;
                    }

                    if (!string.IsNullOrWhiteSpace(drugInfo))
                    {
                        return (false, $"该药品（{drugInfo}）不存在或已禁用，请先在药品入库模块中创建该药品。", null);
                    }
                    else
                    {
                        return (false, "该检药单未关联药品信息，无法发药。请先在药品入库模块中创建对应药品。", null);
                    }
                }

                // 检查库存
                if (drug.Inventory <= 0)
                {
                    return (false, $"该药品（{drug.DrugName}）库存为0，当前库存：{drug.Inventory}，请先在药品入库模块中补充库存后再进行发药操作。", drug.DrugId);
                }

                // 获取处方明细的数量信息（如果可能）
                int requiredQuantity = 1; // 默认值
                try
                {
                    // 尝试从处方明细获取数量
                    var prescriptionResponse = await _httpClient.GetAsync($"api/Prescription/GetByAppointment?appointmentId={inspection.AppointmentId}");
                    if (prescriptionResponse.IsSuccessStatusCode)
                    {
                        var prescriptionJson = await prescriptionResponse.Content.ReadAsStringAsync();
                        var prescriptionResult = JsonSerializer.Deserialize<ApiResult<List<Work.API.Dtos.PrescriptionItemDto>>>(prescriptionJson, _jsonOptions);
                        if (prescriptionResult != null && prescriptionResult.Code == ApiEnum.成功 && prescriptionResult.Data != null)
                        {
                            var prescriptionItem = prescriptionResult.Data.FirstOrDefault(pi => pi.PrescriptionItemId == inspection.PrescriptionItemId);
                            if (prescriptionItem != null)
                            {
                                requiredQuantity = prescriptionItem.Quantity;
                            }
                        }
                    }
                }
                catch
                {
                    // 如果获取处方明细失败，使用默认值
                }

                // 检查库存是否充足
                if (drug.Inventory < requiredQuantity)
                {
                    return (false, $"该药品（{drug.DrugName}）库存不足，当前库存：{drug.Inventory}，需要数量：{requiredQuantity}，请先在药品入库模块中补充库存后再进行发药操作。", drug.DrugId);
                }

                return (true, $"库存充足，当前库存：{drug.Inventory}，可以发药。", drug.DrugId);
            }
            catch (Exception ex)
            {
                return (false, $"检查库存时发生错误：{ex.Message}，请稍后重试。", null);
            }
        }

        /// <summary>
        /// 选择未打单处方明细（左侧）
        /// </summary>
        private void dgvUndispensed_SelectionChanged(object sender, EventArgs e)
        {
            if (dgvUndispensed.SelectedRows.Count > 0)
            {
                var selectedRow = dgvUndispensed.SelectedRows[0];
                if (selectedRow.DataBoundItem is UnbilledPrescriptionDto prescription)
                {
                    _selectedUnbilledPrescription = prescription;
                }
            }
        }

        /// <summary>
        /// 选择检药单（右侧）
        /// </summary>
        private void dgvDispensed_SelectionChanged(object sender, EventArgs e)
        {
            if (dgvDispensed.SelectedRows.Count > 0)
            {
                var selectedRow = dgvDispensed.SelectedRows[0];
                if (selectedRow.DataBoundItem is InspectionListDto inspection)
                {
                    _selectedInspection = inspection;
                }
            }
        }
    }
}
